package org.umlviewer.model;

import org.umlviewer.paint.PaintUtils;
import java.awt.*;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;

/**
 *
 * @author Rafa
 */
public abstract class Relationship extends DrawElement{
    
    private String srcMultiplicity;
    private String dstMultiplicity;
    private int type; /* asociacion, generealizacion, etc. */
    private DiagramElement destination;
    private DiagramElement source;
    //constatntes para los tipos de realaciones
    public static final int ASSOCIATION = 1;
    public static final int GENERALIZATION = 2;
    public static final int COMPOSITION = 3;
    public static final int AGGREGATION = 4;
    public static final int REALITATION = 5;
    public static final int DEPENDENCY = 6;
    public static final int MESSAGE = 7;
    public static final int INCLUDE = 8;
    public static final int EXTEND = 9;
    //color de la linea
    private Color lineColor = Color.BLACK;    

    public Relationship()
    {
        setName("");
        type=0;
        srcMultiplicity = "";
        dstMultiplicity="";        
    }    
    
     public Relationship(String label, int type, DiagramElement source, DiagramElement destination) {
        setName(label);
        this.type = type;
        this.destination = destination;
        this.source = source;
        srcMultiplicity = "";
        dstMultiplicity="";        
    }  
    
    public DiagramElement getDestination() {
        return destination;
    }

    public void setDestination(DiagramElement destination) {
        this.destination = destination;
    }

    public DiagramElement getSource() {
        return source;
    }

    public void setSource(DiagramElement source) {
        this.source = source;
    }        

    public String getLabel() {
        return getName();
    }

    public void setLabel(String label) {
        setName(label);
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getDstMultiplicity() {
        return dstMultiplicity;
    }

    public void setDstMultiplicity(String dstMultiplicity) {
        this.dstMultiplicity = dstMultiplicity;
    }

    public String getSrcMultiplicity() {
        return srcMultiplicity;
    }

    public void setSrcMultiplicity(String srcMultiplicity) {
        this.srcMultiplicity = srcMultiplicity;
    }        
    
    //contains generico para una relacion sencilla
    //se deberia sobreescribir para otro tipo de relacion
    @Override
    public boolean contains(int x, int y){
//        if(line!=null){            
//            return (line.ptSegDist(x, y)<=4.0);
//        }
//        return false;
        double dstX, dstY;
        double srcX, srcY;       
        
        if(source!=null && destination!=null){
            Point2D q = source.getRelPoint(destination.getMidPoint());
            srcX = q.getX();
            srcY = q.getY(); 

            Point2D p = destination.getRelPoint(source.getMidPoint());
            dstX = p.getX();
            dstY = p.getY();        
            
            return (PaintUtils.ptSegDist(srcX, srcY, dstX, dstY, x, y)<=4.0);
        }
        return false;
    }
    
    //Estos metodos no se implementan, solo para poder heredar de DrawElement    
    public Rectangle getBounds(){
        return new Rectangle(0,0,0,0);
    }
    
    public void resize(Rectangle r){
        ;
    }
                          
    public void move(int x, int y){
        ;
    }
    //
    
    public abstract void paint(Graphics g2);
    
    //funciona invertida, de src -> dst devuelve las posiciones de dst
    //se cambio la forma de pintar las relaciones, se mantiene esta funcion
    //si se desea volver a tras
    private Point2D getRelPoint(DiagramElement src, DiagramElement dst)
    {
        Point2D ret = null;
        double dstX, dstY;
        double srcX, srcY;              
         //punto medio inicial
        srcX = src.getPosX() + src.getWidth()/2;
        srcY = src.getPosY() + src.getHeight()/2;
        //punto medio final 
        dstX = dst.getPosX() + dst.getWidth()/2;
        dstY = dst.getPosY() + dst.getHeight()/2;
        
        double angle = Math.atan2((double) (srcX - dstX),
                        (double) (srcY - dstY));
        dstX = ((Math.sin(angle) * dst.getWidth()/2)) + dstX;
        dstY = ((Math.cos(angle) * dst.getHeight()/2)) + dstY;        
        
        ret = new Point2D.Double(dstX,dstY);
        return ret;
    }
    
    private Point2D getRel2(DiagramElement src, DiagramElement dst){
        Point2D ret = null;
        Point ref = new Point(dst.getPosX(), dst.getPosY());
         ret = PaintUtils.ptClosestTo(src.getBounds(), ref);        
        return ret;
    }

    public Color getLineColor() {
        return this.lineColor;
    }
    
    public void setLineColor(Color c){
        this.lineColor  = c;
    }        
}
